/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.inspur.edp.jittojava.core;

import com.inspur.edp.jittojava.context.entity.MavenDependency;
import com.inspur.edp.jittojava.core.manager.GeneratorManager;
import com.inspur.edp.jittojava.core.manager.GeneratorManagerFactory;
import com.inspur.edp.lcm.metadata.common.Utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.dom4j.Document;
import org.dom4j.Element;

public class GenerateServiceCore {
    public void generate(String absolutePath, String mavenPath) throws Exception {
        final GeneratorManager generatorManager = GeneratorManagerFactory.createGeneratorManager(absolutePath);
        generatorManager.generate(absolutePath, mavenPath);
    }

    public void generateApi(String absolutePath, String mavenPath) throws Exception {
        final GeneratorManager generatorManager = GeneratorManagerFactory.createGeneratorManager(absolutePath);
        generatorManager.generateApi(absolutePath, mavenPath);
    }

    public void removeRuntimeModule(String absolutePath) {
        String pomPath = getPomFilePath(absolutePath);
        Model model = getModel(pomPath);
        List<String> modules = model.getModules();
        List<String> newMudules = modules.stream().filter(module -> !"runtime".equals(module)).collect(Collectors.toList());
        model.setModules(newMudules);
        writeModel(pomPath, model);
    }

    public void writeModel(String pomPath, Model model) {
        File pom = new File(pomPath);
        if (!pom.exists()) {
            pom.getParentFile().mkdirs();
            try {
                pom.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try (FileOutputStream fileOutputStream = new FileOutputStream(pomPath)) {
            MavenXpp3Writer mavenXpp3Writer = new MavenXpp3Writer();
            mavenXpp3Writer.write(fileOutputStream, model);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public Model getModel(String pomPath) {
        try (FileInputStream fis = new FileInputStream(pomPath)) {
            MavenXpp3Reader reader = new MavenXpp3Reader();
            final Model model = reader.read(fis);
            return model;
        } catch (IOException | XmlPullParserException e) {
            throw new RuntimeException(e);
        }
    }

    public void modifyPom(String absolutePath, List<MavenDependency> mavenDependencyList) {
        if (mavenDependencyList == null || mavenDependencyList.size() == 0) {
            return;
        }
        String pomPath = getPomFilePath(absolutePath);
        Document doc = JitUtils.readDocument(pomPath);
        Element projectElement = doc.getRootElement();
        Element dependenciesElement = projectElement.element(MavenDependencyConst.dependencies);

        if (dependenciesElement == null) {
            dependenciesElement = projectElement.addElement(MavenDependencyConst.dependencies);
        }
        List<Element> existValues = dependenciesElement.elements();
        ArrayList<MavenDependency> existDependencies = JitUtils.readExistDependencies(existValues);
        for (MavenDependency newDependency : mavenDependencyList) {
            if (JitUtils.checkContainDependency(newDependency, existDependencies)) {
                continue;
            }
            JitUtils.addDependencyDom(newDependency, dependenciesElement);
        }
        JitUtils.saveDocument(doc, new File(pomPath));
    }

    private String getPomFilePath(String projPath) {
        String javaPath = Paths.get(projPath).resolve("java").toString();
        String javaProjPath = Paths.get(javaPath).resolve(Utils.getMavenProName()).toString();
        String pomFilePath = Paths.get(javaProjPath).resolve("pom.xml").toString();

        return pomFilePath;
    }

}
